/**
 * Copyright (c) 2008 Luciano Bustos - riaevolution.com, All Rights Reserved.
 *
 * Contact luchyx@riaevolution.com
 *
 * See www.riaevolution.com
 * See www.riaevolution.com/blog
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * */
package com.riaevolution.google {
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.utils.clearTimeout;
	import flash.utils.setTimeout;

	import mx.utils.URLUtil;


	[Event(name="urlChanged")]


	/**
	 * Static map mini api for flex applications.
	 * Allow you to generate Static url for google static maps api.
	 *
	 * Zoom 15 & size 320 seems to be good.
	 *
	 *
	 *
	 * @author Luciano Bustos
	 * @see http://www.riaevolution.com
	 * @see http://code.google.com/apis/maps/documentation/staticmaps
	 */
	public class StaticMap extends EventDispatcher {

		public function StaticMap() {
			super(null);
			//this values are required
			_token['size'] = "320x320";
			_token['sensor'] = "false";
		}

		/**
		 * Static URL provides you with an static image that not count requests.
		 * Because the maps.google.static API look the user if they request exced 500 per day.<br />
		 * <b>Use this value when testing</b>
		 *
		 * @return String a static url with zoom = 15 and size = 320.
		 *
		 */
		public function get testUrl():String {
			//Please define a key on flex compiler args:
			//-define=GOOGLE::key,'your key value'
			return "http://maps.google.com/maps/api/staticmap?key=" + mapKey + "&size=320x320&markers=Catulo Castillo 3090, Buenos Aires, Argentina&sensor=false&zoom=15";
		}

		/**
		 * The image type allowed by the service.
		 * @return  Array of alllowed options
		 * @see http://code.google.com/apis/maps/documentation/staticmaps/#ImageFormats
		 */
		public static function asDataProvider():Array {
			return [GIF, JPG, JPG_B, PNG_8, PNG_32];
		}

		/**
		 *  (default) specifies the GIF format.
		 */
		public static const GIF:String = "gif";

		/**
		 * specifies the JPEG compression format.
		 */
		public static const JPG:String = "jpg";

		/**
		 *  specifies a non-progressive JPEG compression format.
		 */
		public static const JPG_B:String = "jpg-baseline";

		/**
		 * specifies the 8-bit PNG format.
		 */
		public static const PNG_8:String = "png8";
		/**
		 * specifies the 32-bit PNG format.
		 */
		public static const PNG_32:String = "png32";

		/**
		 * the default url
		 */
		public static const STATIC_URL:String = "http://maps.google.com/maps/api/staticmap";

		private var _mapKey:String;

		/**
		 * Getter setter for map key
		 * @return
		 */
		[Bindable]
		public function get mapKey():String {
			return _mapKey;
		}

		public function set mapKey(value:String):void {
			_mapKey = value;
			_token['key'] = _mapKey;
		}


		//http://maps.google.com/maps/api/staticmap?center=-34.635082,-58.407587&zoom=13&markers=size:small|color:blue|-34.635082,-58.407587&size=320x320&sensor=false&key=ABQIAAAAjU0EJWnWPMv7oQ-jjS7dYxSPW5CJgpdgO_s4yyMovOaVh_KvvhSfpvagV18eOyDWu7VytS6Bi1CWxw
		//markers

		private var _token:Object = {};

		private var _preventDispatchTO:int;

		private function urlchanged():void {
			//this prevent execisive dispatch event
			if (_preventDispatchTO) {
				clearTimeout(_preventDispatchTO);
			}
			setTimeout(this.dispatchEvent, 800, new Event("urlChanged"));
		}

		public function set maptype(type:String):void {
			_token['maptype'] = type;
			urlchanged();
		}

		public function set zoomLevel(level:Number):void {
			_token['zoom'] = level;
			urlchanged();
		}

		public function size(w:Number, h:Number):void {
			_token['size'] = w + "x" + h;
			urlchanged();
		}

		private var _height:Number = 320;

		public function get height():Number {
			return _height;
		}

		[Bindable]
		public function set height(value:Number):void {
			_height = value;
			size(width, height);
		}


		private var _width:Number = 320;

		public function get width():Number {
			return _width;
		}

		[Bindable]
		public function set width(value:Number):void {
			_width = value;
			size(width, height);
		}


		/**
		 * string address (e.g. "city hall, new york, ny")
		 *
		 * <listing>
		 * address("Catulo castillo 3090, buenos aires, argentina");
		 * </listing>
		 * @param value
		 *
		 */
		public function set address(value:String):void {
			_token['center'] = value;
			urlchanged();
		}

		/**
		 * Specify latitud and longitud
		 * <listing>
		 * LatLong(40.714728,-73.998672)
		 * </listing>
		 *
		 * @param lat
		 * @param long
		 *
		 */
		public function LatLong(lat:Number, long:Number):void {
			//center=40.714728,-73.998672
			_token['center'] = lat.toString() + "," + long.toString();
			urlchanged();
		}

		private var _markers:Array = [];


		/**
		 * remueve todas las markers agregadas.
		 */
		public function clearMarkers():void {
			_markers = [];
			_token['markers'] = null;
			delete _token['markers'];
		}

		/**
		 * Advanced method to add a marker
		 * markers=size:tiny|color:blue|label:S|62.107733,-145.541936
		 *
		 * @param latlongOrAddres
		 * @param size tiny, mid, small
		 * @param color 24-bit color example: color=0xFFFFCC
		 */
		public function addMarker(latlongOrAddres:String, size:String, color:String):void {
			var mrk:Array = [];
			if (size) {
				mrk.push("size:" + size);
			}
			if (color) {
				mrk.push("color:" + color);
			}
			mrk.push(latlongOrAddres);
			this.markers = mrk.join("|");
		}

		/**
		 *  Push markers allow you to display a set of markers. instead of only one.
		 */
		public var pushMarkers:Boolean = false;

		/**
		 * add a marker option
		 *
		 * @param marker string of marker format
		 * @see http://code.google.com/apis/maps/documentation/staticmaps/#Markers
		 */
		public function set markers(marker:String):void {
			if (pushMarkers == false) {
				_markers = [];
			}
			_markers.push(marker);
			_token['markers'] = _markers.join("&");
			urlchanged();
		}

		/**
		 * Getter para la url generada de maps
		 */
		[Bindable("urlChanged")]
		public function get url():String {
			//si tengo markers no tomo el token de "center"
			if (_markers && _markers.length > 0) {
				delete _token['center'];
			}
			return STATIC_URL + "?" + URLUtil.objectToString(_token, "&", false);
		}
	}
}